<!DOCTYPE html>
<html lang="en">
<head>
  <title>Vert.x Service Proxy - Vert.x</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <meta content="Vert.x is a tool-kit for building reactive applications on the JVM." name="description">
  <link href="http://vertx.io/stylesheets/docs.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/stylesheets/font-awesome.min.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/javascripts/styles/rainbow.min.css" media="screen" rel="stylesheet">
  <!-- IE 6-8 support of HTML 5 elements -->
  <!--[if lt IE 9]>
  <script src="http://static.jboss.org/theme/js/libs/html5/pre3.6/html5.min.js"></script>
  <![endif]-->

  <link rel="apple-touch-icon" sizes="57x57" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-57x57.png">
  <link rel="apple-touch-icon" sizes="60x60" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-60x60.png">
  <link rel="apple-touch-icon" sizes="72x72" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-72x72.png">
  <link rel="apple-touch-icon" sizes="76x76" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-76x76.png">
  <link rel="apple-touch-icon" sizes="114x114" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-114x114.png">
  <link rel="apple-touch-icon" sizes="120x120" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-120x120.png">
  <link rel="apple-touch-icon" sizes="144x144" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-144x144.png">
  <link rel="apple-touch-icon" sizes="152x152" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-152x152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-180x180.png">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-32x32.png" sizes="32x32">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/android-chrome-192x192.png" sizes="192x192">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-96x96.png" sizes="96x96">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-16x16.png" sizes="16x16">
  <link rel="manifest" href="http://vertx.io/assets/favicons/vertx-favicon-7/manifest.json">
  <link rel="mask-icon" href="http://vertx.io/assets/favicons/vertx-favicon-7/safari-pinned-tab.svg" color="#5bbad5">
  <meta name="msapplication-TileColor" content="#7d3194">
  <meta name="msapplication-TileImage" content="http://vertx.io/assets/favicons/vertx-favicon-7/mstile-144x144.png">
  <meta name="theme-color" content="#ffffff">

  <link href="http://fonts.googleapis.com/css?family=Ubuntu:400,500,700,400italic" rel="stylesheet" type="text/css">
  <link rel="alternate" type="application/rss+xml" title="RSS"
     href="http://vertx.io/feed.xml">
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-30144458-1', 'auto');
    ga('create', 'UA-71153120-1', 'auto', 'tracker');
    ga('send', 'pageview');
    ga('tracker.send', 'pageview');
  </script>
</head>
<body>

<a href="http://www.reactivemanifesto.org/" id="reactive-manifesto-banner">
  <img style="border: 0; position: fixed; right: 0; top:0; z-index: 9000"
    src="http://d379ifj7s9wntv.cloudfront.net/reactivemanifesto/images/ribbons/we-are-reactive-black-right.png">
</a>

<a id="skippy" class="sr-only sr-only-focusable" href="#content"><div class="container"><span class="skiplink-text">Skip to main content</span></div></a>

<header class="navbar navbar-default navbar-static-top" id="top" role="banner">
  <div class="container">
    <div class="navbar-header">
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#vertx-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a href="http://vertx.io/" class="navbar-brand"><img alt="Brand" src="http://vertx.io/assets/logo-sm.png"></a>
    </div>
    <nav class="collapse navbar-collapse" id="vertx-navbar-collapse">
      <ul class="nav navbar-nav navbar-right">
        <li><a href="http://vertx.io/download/">Download</a></li>
        <li><a href="http://vertx.io/docs/">Documentation</a></li>
        <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
        <li><a href="http://vertx.io/community/">Community</a></li>
        <li><a href="http://vertx.io/materials/">Materials</a></li>
        <li><a href="http://vertx.io/blog/">Blog</a></li>        
      </ul>
    </nav>
  </div>
</header>



  <div class="page-header" id="content">
    <div class="container">
      <div class="row">
        <div class="col-sm-12">
          <h1>Vert.x Service Proxy</h1>
          
        </div>
      </div>
    </div>
  </div>




<div id="content">
  <div class="container docs-content">
    <div class="row">
      <div class="col-sm-12 col-md-push-9 col-md-3 hidden-xs hidden-sm">
        <div id="sidebar" data-spy="affix">
          <ul class="sectlevel1">
<li><a href="#_using_vert_x_service_proxies">Using vert.x service proxies</a></li>
<li><a href="#_introduction_to_service_proxies">Introduction to service proxies</a></li>
<li><a href="#_async_interface">Async Interface</a></li>
<li><a href="#_code_generation">Code generation</a></li>
<li><a href="#_exposing_your_service">Exposing your service</a></li>
<li><a href="#_proxy_creation">Proxy creation</a></li>
<li><a href="#_error_handling">Error Handling</a></li>
<li><a href="#_restrictions_for_service_interface">Restrictions for service interface</a>
<ul class="sectlevel2">
<li><a href="#_return_types">Return types</a></li>
<li><a href="#_overloaded_methods">Overloaded methods</a></li>
</ul>
</li>
<li><a href="#_convention_for_invoking_services_over_the_event_bus_without_proxies">Convention for invoking services over the event bus (without proxies)</a></li>
</ul>
        </div>
      </div>
      <div class="col-sm-12 col-md-pull-3 col-md-9">
        <div class="toc hidden-md hidden-lg">
          <h2>Table of Contents</h2>
          <ul class="sectlevel1">
<li><a href="#_using_vert_x_service_proxies">Using vert.x service proxies</a></li>
<li><a href="#_introduction_to_service_proxies">Introduction to service proxies</a></li>
<li><a href="#_async_interface">Async Interface</a></li>
<li><a href="#_code_generation">Code generation</a></li>
<li><a href="#_exposing_your_service">Exposing your service</a></li>
<li><a href="#_proxy_creation">Proxy creation</a></li>
<li><a href="#_error_handling">Error Handling</a></li>
<li><a href="#_restrictions_for_service_interface">Restrictions for service interface</a>
<ul class="sectlevel2">
<li><a href="#_return_types">Return types</a></li>
<li><a href="#_overloaded_methods">Overloaded methods</a></li>
</ul>
</li>
<li><a href="#_convention_for_invoking_services_over_the_event_bus_without_proxies">Convention for invoking services over the event bus (without proxies)</a></li>
</ul>
        </div>
        <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>When you compose a vert.x application, you may want to isolate a functionality somewhere and make it available to
the rest of your application.</p>
</div>
<div class="paragraph">
<p>That&#8217;s the main purpose of service proxies. It lets you expose a <em>service</em> on the
event bus, so, any other vert.x component can consume it, as soon as they know the <em>address</em> on which the service
is published.</p>
</div>
<div class="paragraph">
<p>A <em>service</em> is described with a Java interface containing methods following the <em>async pattern</em>. Behind the hood,
messages are sent on the event bus to invoke the service and get the response back. But to make it more easy to use
for you, it generates a <em>proxy</em> that you can invoke directly (using the API  from the service interface).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_vert_x_service_proxies">Using vert.x service proxies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To use the Vert.x Service Proxies, add the following dependency to the <em>dependencies</em> section of
your build descriptor:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Maven (in your <code>pom.xml</code>):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;io.vertx&lt;/groupId&gt;
  &lt;artifactId&gt;vertx-service-proxy&lt;/artifactId&gt;
  &lt;version&gt;3.3.3&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Gradle (in your <code>build.gradle</code> file):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-groovy" data-lang="groovy">compile 'io.vertx:vertx-service-proxy:3.3.3'</code></pre>
</div>
</div>
<div class="paragraph">
<p>Be aware that as the service proxy mechanism relies on code generation, so modifications to the <em>service interface</em>
require to re-compile the sources to regenerate the code.</p>
</div>
<div class="paragraph">
<p>To generate the proxies in different languages, you will need to add the <em>language</em> dependency such as
<code>vertx-lang-groovy</code> for Groovy&#8230;&#8203;.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_introduction_to_service_proxies">Introduction to service proxies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let&#8217;s have a look to service proxies and why they can be useful. Let&#8217;s imagine you have a <em>database service</em>
exposed on the event bus, you should do something like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">JsonObject message = new JsonObject();
message.put("collection", "mycollection")
    .put("document", new JsonObject().put("name", "tim"));
DeliveryOptions options = new DeliveryOptions().addHeader("action", "save");
vertx.eventBus().send("database-service-address", message, options, res2 -&gt; {
  if (res2.succeeded()) {
    // done
  } else {
    // failure
  }
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>When creating a service there&#8217;s a certain amount of boilerplate code to listen on the event bus for incoming
messages, route them to the appropriate method and return results on the event bus.</p>
</div>
<div class="paragraph">
<p>With Vert.x service proxies, you can avoid writing all that boilerplate code and concentrate on writing your service.</p>
</div>
<div class="paragraph">
<p>You write your service as a Java interface and annotate it with the <code>@ProxyGen</code> annotation, for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@ProxyGen
public interface SomeDatabaseService {

  // A couple of factory methods to create an instance and a proxy
  static SomeDatabaseService create(Vertx vertx) {
    return new SomeDatabaseServiceImpl(vertx);
  }

  static SomeDatabaseService createProxy(Vertx vertx,
    String address) {
    return new SomeDatabaseServiceVertxEBProxy(vertx, address);
  }

 // Actual service operations here...
 void save(String collection, JsonObject document,
   Handler&lt;AsyncResult&lt;Void&gt;&gt; resultHandler);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Given the interface, Vert.x will generate all the boilerplate code required to access your service over the event
bus, and it will also generate a <strong>client side proxy</strong> for your service, so your clients can use a rich idiomatic
API for your service instead of having to manually craft event bus messages to send. The client side proxy will
work irrespective of where your service actually lives on the event bus (potentially on a different machine).</p>
</div>
<div class="paragraph">
<p>That means you can interact with your service like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">SomeDatabaseService service = SomeDatabaseService.createProxy(vertx,
    "database-service-address");

// Save some data in the database - this time using the proxy
service.save("mycollection", new JsonObject().put("name", "tim"), res2 -&gt; {
  if (res2.succeeded()) {
    // done
  }
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also combine <code>@ProxyGen</code> with language API code generation (<code>@VertxGen</code>) in order to create service stubs
in any of the languages supported by Vert.x - this means you can write your service once in Java and interact with it
through an idiomatic other language API irrespective of whether the service lives locally or is somewhere else on
the event bus entirely. For this don&#8217;t forget to add the dependency on your language in your build descriptor:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@ProxyGen // Generate service proxies
@VertxGen // Generate the clients
public interface SomeDatabaseService {
  // ...
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_async_interface">Async Interface</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To be used by the service-proxy generation, the <em>service interface</em> must comply to a couple of rules. First it
should follow the async pattern. To return result, the method should declare a
<code>Handler&lt;AsyncResult&lt;ResultType&gt;&gt;</code>. <code>ResultType</code> can be another proxy (and so a proxies can be factories for other
proxies.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s see an example</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@ProxyGen
public interface SomeDatabaseService {

 // A couple of factory methods to create an instance and a proxy

 static SomeDatabaseService create(Vertx vertx) {
   return new SomeDatabaseServiceImpl(vertx);
 }

 static SomeDatabaseService createProxy(Vertx vertx, String address) {
   return new SomeDatabaseServiceVertxEBProxy(vertx, address);
 }

 // A method notifying the completion without a result (void)
 void save(String collection, JsonObject document,
   Handler&lt;AsyncResult&lt;Void&gt;&gt; result);

 // A method providing a result (a json object)
 void findOne(String collection, JsonObject query,
   Handler&lt;AsyncResult&lt;JsonObject&gt;&gt; result);

 // Create a connection
 void createConnection(String shoeSize,
   Handler&lt;AsyncResult&lt;MyDatabaseConnection&gt;&gt; resultHandler);

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@ProxyGen
@VertxGen
public interface MyDatabaseConnection {

 void insert(JsonObject someData);

 void commit(Handler&lt;AsyncResult&lt;Void&gt;&gt; resultHandler);

 @ProxyClose
 void close();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also declare that a particular method unregisters the proxy by annotating it with the <code>@ProxyClose</code>
annotation. The proxy instance is disposed when this method is called.</p>
</div>
<div class="paragraph">
<p>More constraints on the <em>service interfaces</em> are described below.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_code_generation">Code generation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Service annotated with <code>@ProxyGen</code> annotation trigger the generation of the service helper classes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The service proxy: a compile time generated proxy that uses the <code>EventBus</code> to interact with the service via messages</p>
</li>
<li>
<p>The service handler: a compile time generated <code>EventBus</code> handler that reacts to events sent by the proxy</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Generated proxies and handlers are named after the service class, for example if the service is named <code>MyService</code>
the handler is called <code>MyServiceProxyHandler</code> and the proxy is called <code>MyServiceEBProxy</code>.</p>
</div>
<div class="paragraph">
<p>The <em>codegen</em> annotation processor generates these classes at compilation time. It is a feature of the Java
compiler so <em>no extra step</em> is required, it is just a matter of configuring correctly the compiler.</p>
</div>
<div class="paragraph">
<p>Here a configuration example for Maven:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;plugin&gt;
  &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
  &lt;configuration&gt;
    &lt;annotationProcessors&gt;
      &lt;annotationProcessor&gt;io.vertx.codegen.CodeGenProcessor&lt;/annotationProcessor&gt;
    &lt;/annotationProcessors&gt;
    &lt;compilerArgs&gt;
      &lt;arg&gt;-AoutputDirectory=${project.basedir}/src/main&lt;/arg&gt;
    &lt;/compilerArgs&gt;
  &lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This feature can also be used in Gradle, or even in IDE as they provide usually support for annotation
processors.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_exposing_your_service">Exposing your service</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Once you have your <em>service interface</em>, compile the source to generate the stub and proxies. Then, you need some
code to "register" your service on the event bus:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">SomeDatabaseService service = new SomeDatabaseServiceImpl();
// Register the handler
ProxyHelper.registerService(SomeDatabaseService.class, vertx, service,
    "database-service-address");</code></pre>
</div>
</div>
<div class="paragraph">
<p>This can be done in a verticle, or anywhere in your code.</p>
</div>
<div class="paragraph">
<p>Once registered, the service becomes accessible. If you are running your application on a cluster, the service is
available from any host.</p>
</div>
<div class="paragraph">
<p>To withdraw your service, use the <code><a href="../../apidocs/io/vertx/serviceproxy/ProxyHelper.html#unregisterService-io.vertx.core.eventbus.MessageConsumer-">ProxyHelper.unregisterService</a></code>
method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">SomeDatabaseService service = new SomeDatabaseServiceImpl();
// Register the handler
MessageConsumer&lt;JsonObject&gt; consumer = ProxyHelper.registerService(SomeDatabaseService.class, vertx, service,
    "database-service-address");

// ....

// Unregister your service.
ProxyHelper.unregisterService(consumer);</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_proxy_creation">Proxy creation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Now that the service is exposed, you probably want to consume it. For this, you need to create a proxy. The proxy
can be created using the <code>ProxyHelper</code> class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">SomeDatabaseService service = ProxyHelper.createProxy(SomeDatabaseService.class,
    vertx,
    "database-service-address");
// or with delivery options:
SomeDatabaseService service2 = ProxyHelper.createProxy(SomeDatabaseService.class,
    vertx,
    "database-service-address", options);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The second method takes an instance of <code><a href="../../apidocs/io/vertx/core/eventbus/DeliveryOptions.html">DeliveryOptions</a></code> where you con configure the
message delivery (such as the timeout).</p>
</div>
<div class="paragraph">
<p>Alternatively, you can use the generated proxy class. The proxy class name is the <em>service interface</em> class name
followed by <code>VertxEBProxy</code>. For instance, if your <em>service interface</em> is named <code>SomeDatabaseService</code>, the proxy
class is named <code>SomeDatabaseServiceVertxEBProxy</code>.</p>
</div>
<div class="paragraph">
<p>Generally, <em>service interface</em> contains a <code>createProxy</code> static method to create the proxy. But this is not required:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@ProxyGen
public interface SomeDatabaseService {

 // Method to create the proxy.
 static SomeDatabaseService createProxy(Vertx vertx, String address) {
   return new SomeDatabaseServiceVertxEBProxy(vertx, address);
 }

 // ...
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_error_handling">Error Handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Service methods may return errors to the client by passing a failed <code>Future</code> containing a <code><a href="../../apidocs/io/vertx/serviceproxy/ServiceException.html">ServiceException</a></code>
instance to the method&#8217;s <code>Handler</code>. A <code>ServiceException</code> contains an <code>int</code> failure code, a message, and an optional
<code>JsonObject</code> containing any extra information deemed important to return to the caller. For convenience, the
<code><a href="../../apidocs/io/vertx/serviceproxy/ServiceException.html#fail-int-java.lang.String-">ServiceException.fail</a></code> factory method can be used to create an instance of
<code>ServiceException</code> already wrapped in a failed <code>Future</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class SomeDatabaseServiceImpl implements SomeDatabaseService {
private static final BAD_SHOE_SIZE = 42;
private static final CONNECTION_FAILED = 43;

  // Create a connection
  void createConnection(String shoeSize, Handler&lt;AsyncResult&lt;MyDatabaseConnection&gt;&gt; resultHandler) {
    if (!shoeSize.equals("9")) {
      resultHandler.handle(ServiceException.fail(BAD_SHOE_SIZE, "The shoe size must be 9!",
        new JsonObject().put("shoeSize", shoeSize));
     } else {
        doDbConnection(result -&gt; {
          if (result.succeeded()) {
            resultHandler.handle(Future.succeededFuture(result.result()));
          } else {
            resultHandler.handle(ServiceException.fail(CONNECTION_FAILED, result.cause().getMessage()));
          }
        });
     }
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The client side can then check if the <code>Throwable</code> it receives from a failed <code>AsyncResult</code> is a <code>ServiceException</code>,
and if so, check the specific error code inside. It can use this information to differentiate business logic
errors from system errors (like the service not being registered with the Event Bus), and to determine exactly
which business logic error occurred.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public void foo(String shoeSize, Handler&lt;AsyncResult&lt;JsonObject&gt;&gt; handler) {
  SomeDatabaseService service = SomeDatabaseService.createProxy(vertx, SERVICE_ADDRESS);
  service.createConnection("8", result -&gt; {
    if (result.succeeded()) {
      // Do success stuff.
    } else {
      if (result.cause() instanceof ServiceException) {
        ServiceException exc = (ServiceException) result.cause();
        if (exc.failureCode() == SomeDatabaseServiceImpl.BAD_SHOE_SIZE) {
          handler.handle(Future.failedFuture(
            new InvalidInputError("You provided a bad shoe size: " +
              exc.getDebugInfo().getString("shoeSize"))
          ));
        } else if (exc.failureCode() == SomeDatabaseServiceImpl.CONNECTION) {
          handler.handle(Future.failedFuture(
            new ConnectionError("Failed to connect to the DB")));
        }
      } else {
        // Must be a system error (e.g. No service registered for the proxy)
        handler.handle(Future.failedFuture(
          new SystemError("An unexpected error occurred: + " result.cause().getMessage())
        ));
      }
    }
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If desired, service implementations may also return a sub-class of <code>ServiceException</code>, as long as a
default <code>MessageCodec</code> is registered for it . For example, given the following <code>ServiceException</code> sub-class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">class ShoeSizeException extends ServiceException {
  public static final BAD_SHOE_SIZE_ERROR = 42;

  private final String shoeSize;

  public ShoeSizeException(String shoeSize) {
    super(BAD_SHOE_SIZE_ERROR, "In invalid shoe size was received: " + shoeSize);
    this.shoeSize = shoeSize;
  }

  public String getShoeSize() {
    return extra;
  }

  public static &lt;T&gt; AsyncResult&lt;T&gt; fail(int failureCode, String message, String shoeSize) {
    return Future.failedFuture(new MyServiceException(failureCode, message, shoeSize));
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As long as a default <code>MessageCodec</code> is registered, the Service implementation can return the custom
exception directly to the caller:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class SomeDatabaseServiceImpl implements SomeDatabaseService {
  public SomeDataBaseServiceImpl(Vertx vertx) {
    // Register on the service side. If using a local event bus, this is all
    // that's required, since the proxy side will share the same Vertx instance.
  SomeDatabaseService service = SomeDatabaseService.createProxy(vertx, SERVICE_ADDRESS);
    vertx.eventBus().registerDefaultCodec(ShoeSizeException.class,
      new ShoeSizeExceptionMessageCodec());
  }

  // Create a connection
  void createConnection(String shoeSize, Handler&lt;AsyncResult&lt;MyDatabaseConnection&gt;&gt; resultHandler) {
    if (!shoeSize.equals("9")) {
      resultHandler.handle(ShoeSizeException.fail(shoeSize));
    } else {
      // Create the connection here
      resultHandler.Handle(Future.succeededFuture(myDbConnection));
    }
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Finally, the client can now check for the custom exception:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public void foo(String shoeSize, Handler&lt;AsyncResult&lt;JsonObject&gt;&gt; handler) {
  // If this code is running on a different node in the cluster, the
  // ShoeSizeExceptionMessageCodec will need to be registered with the
  // Vertx instance on this node, too.
  SomeDatabaseService service = SomeDatabaseService.createProxy(vertx, SERVICE_ADDRESS);
  service.createConnection("8", result -&gt; {
    if (result.succeeded()) {
      // Do success stuff.
    } else {
      if (result.cause() instanceof ShoeSizeException) {
        ShoeSizeException exc = (ShoeSizeException) result.cause();
        handler.handle(Future.failedFuture(
          new InvalidInputError("You provided a bad shoe size: " + exc.getShoeSize())));
      } else {
        // Must be a system error (e.g. No service registered for the proxy)
        handler.handle(Future.failedFuture(
          new SystemError("An unexpected error occurred: + " result.cause().getMessage())
        ));
      }
    }
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that if you&#8217;re clustering <code>Vertx</code> instances, you&#8217;ll need to register the custom Exception&#8217;s <code>MessageCodec</code>
with each <code>Vertx</code> instance in the cluster.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_restrictions_for_service_interface">Restrictions for service interface</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are restrictions on the types and return values that can be used in a service method so that these are easy to
marshall over event bus messages and so they can be used asynchronously. They are:</p>
</div>
<div class="sect2">
<h3 id="_return_types">Return types</h3>
<div class="paragraph">
<p>Must be one of</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>void</code></p>
</li>
<li>
<p><code>@Fluent</code> and return reference to the service (<code>this</code>):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@Fluent
SomeDatabaseService doSomething();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is because methods must not block and it&#8217;s not possible to return a result immediately without blocking if
the service is remote.</p>
</div>
<div class="sect3">
<h4 id="_parameter_types">Parameter types</h4>
<div class="paragraph">
<p>Let <code>JSON</code> = <code>JsonObject | JsonArray</code>
Let <code>PRIMITIVE</code> = Any primitive type or boxed primitive type</p>
</div>
<div class="paragraph">
<p>Parameters can be any of:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>JSON</code></p>
</li>
<li>
<p><code>PRIMITIVE</code></p>
</li>
<li>
<p><code>List&lt;JSON&gt;</code></p>
</li>
<li>
<p><code>List&lt;PRIMITIVE&gt;</code></p>
</li>
<li>
<p><code>Set&lt;JSON&gt;</code></p>
</li>
<li>
<p><code>Set&lt;PRIMITIVE&gt;</code></p>
</li>
<li>
<p><code>Map&lt;String, JSON&gt;</code></p>
</li>
<li>
<p><code>Map&lt;String, PRIMITIVE&gt;</code></p>
</li>
<li>
<p>Any <em>Enum</em> type</p>
</li>
<li>
<p>Any class annotated with <code>@DataObject</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If an asynchronous result is required a last parameter of type <code>Handler&lt;AsyncResult&lt;R&gt;&gt;</code> can be provided.</p>
</div>
<div class="paragraph">
<p><code>R</code> can be any of:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>JSON</code></p>
</li>
<li>
<p><code>PRIMITIVE</code></p>
</li>
<li>
<p><code>List&lt;JSON&gt;</code></p>
</li>
<li>
<p><code>List&lt;PRIMITIVE&gt;</code></p>
</li>
<li>
<p><code>Set&lt;JSON&gt;</code></p>
</li>
<li>
<p><code>Set&lt;PRIMITIVE&gt;</code></p>
</li>
<li>
<p>Any <em>Enum</em> type</p>
</li>
<li>
<p>Any class annotated with <code>@DataObject</code></p>
</li>
<li>
<p>Another proxy</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_overloaded_methods">Overloaded methods</h3>
<div class="paragraph">
<p>There must be no overloaded service methods. (<em>i.e.</em> more than one with the same name, regardless the signature).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_convention_for_invoking_services_over_the_event_bus_without_proxies">Convention for invoking services over the event bus (without proxies)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Service Proxies assume that event bus messages follow a certain format so they can be used to invoke services.</p>
</div>
<div class="paragraph">
<p>Of course, you don&#8217;t <strong>have to</strong> use client proxies to access remote service if you don&#8217;t want to. It&#8217;s perfectly acceptable
to interact with them by just sending messages over the event bus.</p>
</div>
<div class="paragraph">
<p>In order for services to be interacted with a consistent way the following message formats <strong>must be used</strong> for any
Vert.x services.</p>
</div>
<div class="paragraph">
<p>The format is very simple:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>There should be a header called <code>action</code> which gives the name of the action to perform.</p>
</li>
<li>
<p>The body of the message should be a <code>JsonObject</code>, there should be one field in the object for each argument needed by the action.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For example to invoke an action called <code>save</code> which expects a String collection and a JsonObject document:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Headers:
    "action": "save"
Body:
    {
        "collection", "mycollection",
        "document", {
            "name": "tim"
        }
    }</pre>
</div>
</div>
<div class="paragraph">
<p>The above convention should be used whether or not service proxies are used to create services, as it allows services
to be interacted with consistently.</p>
</div>
<div class="paragraph">
<p>In the case where service proxies are used the "action" value should map to the name of an action method in the
service interface and each <code>[key, value]</code> in the body should map to a <code>[arg_name, arg_value]</code> in the action method.</p>
</div>
<div class="paragraph">
<p>For return values the service should use the <code>message.reply(&#8230;&#8203;)</code> method to send back a return value - this can be of
any type supported by the event bus. To signal a failure the method <code>message.fail(&#8230;&#8203;)</code> should be used.</p>
</div>
<div class="paragraph">
<p>If you are using service proxies the generated code will handle this for you automatically.</p>
</div>
</div>
</div>

        

        
          <div id="footer">
            <div id="footer-text">
              
                Last updated 2016-09-12 08:38:04 CEST
              
              
            </div>
          </div>
        
      </div>
    </div>
  </div>
</div>

<footer>
  <div class="container">
    <div class="row">
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Vert.x</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/">Home</a></li>
          <li><a href="http://vertx.io/download/">Download</a></li>
          <li><a href="http://vertx.io/docs/">Documentation</a></li>
          <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
          <li><a href="http://vertx.io/blog/">Blog</a></li>
          <li><a href="http://vertx.io/vertx2/" class="vertx-2-link">Vert.x 2</a></li>
        </ul>
      </div>
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Community</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/community/">Help &amp; Contributors</a></li>
          <li><a href="http://vertx.io/materials/">Learning materials</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx">User Group</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx-dev">Developer Group</a></li>
        </ul>
      </div>

      <div class="col-xs-12 col-sm-6 col-lg-offset-2 col-md-6 copyright">
        <p>Vert.x is open source and dual licensed under the <a href="https://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License 1.0</a> and <a href="https://www.apache.org/licenses/LICENSE-2.0.html">Apache License 2.0</a>.</p>
        <p>This website is licensed under the <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC BY-SA 3.0 License</a>.<br>
        Design by <a href="http://www.michel-kraemer.com">Michel Kr&auml;mer</a>. <a href="http://www.entypo.com">Entypo pictograms</a> by Daniel Bruce.</p>
        <div class="row">
          <div class="col-xs-12 col-lg-offset-1 col-md-5">
            <a href="http://eclipse.org">
            <img class="logo eclipse-logo" src="http://vertx.io/assets/eclipse_logo_grey_small.png" width="204" height="48">
            </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-0 col-md-5">
            <a href="http://cloudbees.com">
            <img class="logo cloudbees-logo" src="http://vertx.io/assets/Button-Built-on-CB-1-grey.png" width="180" height="48">
           </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-1 col-md-5 jprofiler">
            <a href="http://www.ej-technologies.com/products/jprofiler/overview.html"
            style="text-decoration:none">
            <img class="logo jprofiler-logo" src="http://vertx.io/assets/jprofiler-logo.png" width="48" height="48"><span class="jprofiler-logo">&nbsp; JPROFILER</span>
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</footer>

<script src="http://static.jboss.org/theme/js/libs/jquery/jquery-1.9.1.min.js"></script>
<script src="http://vertx.io/javascripts/bootstrap.min.js"></script>
<script src="http://vertx.io/javascripts/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



<script src="http://vertx.io/javascripts/sidebar.js"></script>


</body>
</html>
